const {
	Service
} = require('uni-cloud-router')

const dbHelper = require('db-helper')
const orderHelper = require('order-helper')
const oneHourInMills = 60 * 60 * 1000

const moment = require('moment-timezone');
const {
	wxPubConfig
} = require("config")
const WxPubApi = require("wx-public-api");
const wxPubApi = new WxPubApi();

const createNoticeMsg = (openId, tempId, motorcade, compere, firstTitle, pagepath) => {
	let path = pagepath ? `pagesScript/motorcade/motorcade-list-dm` : `pagesScript/motorcade/motorcade-list`
	var phone = ''
	if (compere.mobile) {
		phone = compere.mobile.substring(0, 3) + '****' + compere.mobile.substring(7, 11);
	}
	
	return {
		touser: openId,
		template_id: tempId,
		miniprogram: {
			appid: "wxa7e5444036dea6af",
			pagepath: path
		},
		data: {
			first: {
				value: firstTitle
			},
			orderItemName: {
				value: '商品名'
			},
			orderItemData: {
				value: motorcade.name
			},
			tradeDateTime: {
				value: moment().tz("Asia/Shanghai").format("YYYY-MM-DD HH:mm:ss")
			},
			orderType: {
				value: motorcade.type === 'script' ? '剧本' : '-'
			},
			customerInfo: {
				value: `${compere.nickname || '微信用户'} ID: ${compere.id} ${phone}`
			},
			remark: {
				value: `请尽快处理`
			}
		}
	}
}

module.exports = class SubscribeService extends Service {
	async openDoor({
		doorSn
	}) {
		const db = this.db
		const dbCmd = this.db.command
		const $ = dbCmd.aggregate

		try {
			let oneHour = 1000 * 60 * 60
			let {
				data: orderRes
			} = await db.collection('t3ds-order')
				.aggregate()
				.match({
					user_id: this.ctx.auth.uid,
					status: 3,
					type: dbCmd.in(['subscribe', 'tearoom'])
				})
				.lookup({
					from: 't3ds-subscribe-motorcade',
					let: {
						motorcadeId: '$motorcadeId'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.eq(['$_id', '$$motorcadeId'])))
						.project({
							_id: true,
							startTime: true,
							endTime: true,
							storeId: true,
							name: true,
							roomId: true,
							roomName: true,
							storeId: true,
							storeName: true
						})
						.done(),
					as: 'motorcadeInfo',
				})
				.unwind({
					path: '$motorcadeInfo',
					preserveNullAndEmptyArrays: true
				})
				.match({
					'motorcadeInfo.endTime': dbCmd.gt(Date.now() - oneHour - 10000)
				})
				.addFields({
					'motorcadeInfo.start_time': '$motorcadeInfo.startTime',
					'motorcadeInfo.end_time': '$motorcadeInfo.endTime',
					'motorcadeInfo.store_id': '$motorcadeInfo.storeId',
					items0: $.arrayElemAt(['$items', 0])
				})
				.lookup({
					from: 't3ds-store',
					let: {
						storeId: '$items0.store_id'
					},
					pipeline: $.pipeline()
						.match(dbCmd.expr($.eq(['$_id', '$$storeId'])))
						.project({
							_id: true,
							sn: true,
							name: true,
							cooperationMode: true
						})
						.done(),
					as: 'storeInfo',
				})
				.unwind({
					path: '$storeInfo',
					preserveNullAndEmptyArrays: true
				})
				.match({
					'storeInfo.cooperationMode': dbCmd.neq('school')
				})
				.end()
			console.log("orderRes: ", orderRes);
			if (!orderRes.length) throw '没有待使用的订单，无法开门'

			// 是否开大门
			let {
				storeId
			} = await dbHelper.getOne('t3ds-door', {
				sn: doorSn
			})
			let {
				sn: storeSn
			} = await dbHelper.getById('t3ds-store', storeId)
			let isBigDoor = storeSn === doorSn ? true : false
			// console.log("isBigDoor: ",isBigDoor);

			if (isBigDoor) {
				let storeRes = orderRes.filter(orderItem => orderItem.items[0].store_id === storeId)
				console.log("storeRes: ", storeRes);
				if (!storeRes.length) throw '在该门店没有待使用的订单，无法开门'

				let m1 = null
				let m2 = null
				for (let orderItem of orderRes) {
					if (!m1) {
						m1 = orderItem.motorcadeInfo.length ? orderItem.motorcadeInfo : orderItem.items[0]
						m2 = orderItem.motorcadeInfo.length ? orderItem.motorcadeInfo : orderItem.items[0]
					}

					let item = orderItem.motorcadeInfo.length ? orderItem.motorcadeInfo : orderItem.items[0]
					if (item.store_id !== storeId) continue
					if (item.start_time < m1.start_time) {
						m1 = item
					}
					if (item.end_time > m2.end_time) {
						m2 = item
					}
				}
				if (Date.now() < m1.start_time - oneHour) throw '离预约时间大于1小时，无法开门'
				if (Date.now() > m2.end_time + oneHour) throw '结束超过1小时，无法开门'
			} else {
				let currentOrder = ''
				for (let i = 0; i < orderRes.length; i++) {
					let orderItem = orderRes[i]
					let roomId = ''
					if (orderItem.type === 'subscribe') { // 剧本杀
						if (orderItem.motorcadeInfo && orderItem.motorcadeInfo.roomId) {
							roomId = orderItem.motorcadeInfo.roomId
						}
					} else if (currentOrder.type === 'tearoom') { // 茶室
						roomId = orderItem.items[0].room_id
					}
					if (!roomId) continue
					let roomRes = await dbHelper.getById('t3ds-store-room', roomId)
					if (roomRes && roomRes.sn && roomRes.sn === doorSn) {
						currentOrder = orderItem
						break
					}
				}
				console.log("currentOrder: ", currentOrder);
				if (!currentOrder._id) throw '没有预约该房间，无法开门'
				if (currentOrder.type === 'subscribe') { // 剧本杀
					let motorcadeRes = await dbHelper.getById('t3ds-subscribe-motorcade', currentOrder
						.motorcadeId)
					if (Date.now() < motorcadeRes.startTime - oneHour) throw '离预约时间大于1小时，无法开门'
					if (Date.now() > motorcadeRes.endTime + oneHour) throw '结束超过1小时，无法开门'
				} else if (currentOrder.type === 'tearoom') { // 茶室
					if (Date.now() < currentOrder.items[0].start_time - oneHour) throw '离预约时间大于1小时，无法开门'
					if (Date.now() > currentOrder.items[0].end_time + oneHour) throw '结束超过1小时，无法开门'
				}
			}

			// 打开门禁
			let statusRes = await uniCloud.httpclient.request('https://www.wmj.com.cn/api/lockstatus', {
				method: 'POST',
				data: {
					appid: "wmj_gvpz8LlGh5R",
					appsecret: "1wT4d8WsXD7vsEfUwHd55LlEZ94vuSle",
					sn: doorSn
				},
				contentType: 'form-data',
				dataType: 'json'
			})
			console.log("门禁状态结果: ", statusRes.data);
			let res = {}
			if (statusRes.data.state === 0 && statusRes.data.state_code === 5004) {
				throw '门禁设备不存在，请联系管理员开门'
			} else if (!statusRes.data.online) {
				throw '设备不在线，请联系管理员开门'
			} else {
				// 开门
				res = await uniCloud.httpclient.request('https://www.wmj.com.cn/api/oplock', {
					method: 'POST',
					data: {
						appid: "wmj_gvpz8LlGh5R",
						appsecret: "1wT4d8WsXD7vsEfUwHd55LlEZ94vuSle",
						sn: doorSn
					},
					contentType: 'form-data',
					dataType: 'json'
				})
				console.log("开门结果: ", res.data);
				if (res.data.state != 1 && res.data.lock_status != '1') throw res.data.state_msg
			}

			return {
				code: 200,
				result: {
					status: 1,
					text: '开门成功'
				}
			}
		} catch (e) {
			console.log(e);
			return {
				code: 200,
				result: {
					status: 2,
					text: e
				}
			}
		}
	}

	async finishWork({
		motorcadeId
	}) {
		const transaction = await this.db.startTransaction()
		const dbCmd = this.db.command
		const $ = dbCmd.aggregate
		try {
			let motorcade = await dbHelper.getById("t3ds-subscribe-motorcade", motorcadeId, transaction)
			if (!motorcade) {
				throw new Error("车队不存在")
			}
			if (motorcade.compereId != this.ctx.auth.uid) {
				throw new Error("无权限")
			}
			if (motorcade.status != 4) {
				throw new Error("已结束或未确认")
			}
			await dbHelper.update("t3ds-subscribe-motorcade", {
				_id: motorcadeId,
				status: 5,
				finishWorkTime: Date.now(),
				updateTime: Date.now(),
				updateBy: this.ctx.auth.userInfo.username
			}, transaction)
			await dbHelper.update("uni-id-users", {
				_id: this.ctx.auth.uid,
				compereStatus: {
					status: 2,
					storeName: null,
					scriptName: null,
				}
			}, transaction)
      
      let relOrderIdArr = motorcade.orderIds || []
      if (motorcade.renewalOrders) {
        for (let item1 of motorcade.renewalOrders) {
          for (let item2 of item1.renewalOrdersId) {
            relOrderIdArr.push(item2.renewalOrderId)
          }
        }
      }
      console.log("relOrderIdArr: ",relOrderIdArr);
			for (var i = 0; i < relOrderIdArr.length; i++) {
				let orderId = relOrderIdArr[i]
				await dbHelper.update("t3ds-order", {
					_id: orderId,
					status: 4,
					update_time: Date.now()
				}, transaction)
			}
			//结算主持人佣金
			let script = await dbHelper.getById("t3ds-script", motorcade.scriptId)
			var compereBrokerage = 0
			if (script.brokerage) {
				compereBrokerage = (motorcade.currentFemaleCount + motorcade.currentMaleCount) * script
					.brokerage
			} else {
				let brokerageConfig = await dbHelper.getOne("t3ds-system-config", {
					key: 'compereBrokerage'
				})
				if (!brokerageConfig) {
					throw new Error("佣金未配置，请联系管理员")
				}
				compereBrokerage = motorcade.currentCount * parseInt(brokerageConfig.value)
			}
			console.log(`主持人获得佣金：${compereBrokerage / 100}元`)
			if (compereBrokerage) {
				let account = await this.service.cashAccount.getAccountByUid(motorcade.compereId, transaction)
				await dbHelper.update("t3ds-account", {
					_id: account._id,
					balance: dbCmd.inc(compereBrokerage),
					total: dbCmd.inc(compereBrokerage)
				}, transaction)
				await dbHelper.insert("t3ds-account-log", {
					accountId: account._id,
					userId: motorcade.compereId,
					income: compereBrokerage,
					settled: true,
					tradeType: 12,
					settleTime: Date.now(),
					total: account.total + compereBrokerage,
					createTime: Date.now(),
					createBy: this.ctx.auth.userInfo.username,
					motorcadeId: motorcade._id
				}, transaction)
			}
			//结算门店佣金
			let store = await dbHelper.getById("t3ds-store", motorcade.storeId)
			let playTime = (motorcade.endTime - motorcade.startTime) / oneHourInMills

			if (store.cooperationMode == 'alliance') { // 联盟门店
				let room = await dbHelper.getById("t3ds-store-room", motorcade.roomId)
				let brokerage = Math.round(playTime * room.settlementPrice)
				console.log(`房间所有者获得佣金: ${brokerage / 100}元`)
				if (brokerage) {
					let account = await this.service.cashAccount.getAccountByUid(store.uid, transaction)
					await dbHelper.update("t3ds-account", {
						_id: account._id,
						balance: dbCmd.inc(brokerage),
						total: dbCmd.inc(brokerage)
					}, transaction)
					await dbHelper.insert("t3ds-account-log", {
						accountId: account._id,
						userId: store.uid,
						income: brokerage,
						settled: true,
						tradeType: 12,
						settleTime: Date.now(),
						total: account.total + brokerage,
						createTime: Date.now(),
						createBy: this.ctx.auth.userInfo.username,
						motorcadeId: motorcade._id
					}, transaction)
				}
			} else {
				let totalFeeRes = await this.db.collection("t3ds-order").aggregate()
					.match({
						_id: dbCmd.in(relOrderIdArr)
					})
					.group({
						_id: null,
						totalFee: $.sum("$total_fee")
					})
					.end()
				let totalFee = totalFeeRes.data[0].totalFee
				if (totalFee) {
          let serviceChargeConfig = null
          if (!store.commissionRatio) {
            serviceChargeConfig = await dbHelper.getOne("t3ds-system-config", {
            	key: "serviceCharge"
            })
            if (!serviceChargeConfig) { throw new Error("平台抽成比例未配置，请联系管理员") }
          }
					let serviceCharge = Math.round(parseInt(store.commissionRatio || serviceChargeConfig.value) / 100 * totalFee)
					let income = totalFee - serviceCharge
					console.log(`门店收入: ${income / 100}元，平台抽成：${serviceCharge / 100}元`)
					let account = await this.service.cashAccount.getAccountByUid(store.uid, transaction)
					await dbHelper.update("t3ds-account", {
						_id: account._id,
						balance: dbCmd.inc(income),
						total: dbCmd.inc(income)
					}, transaction)
					await dbHelper.insert("t3ds-account-log", {
						accountId: account._id,
						userId: store.uid,
						income: income,
						settled: true,
						tradeType: 12,
						settleTime: Date.now(),
						total: account.total + income,
						createTime: Date.now(),
						createBy: this.ctx.auth.userInfo.username,
						motorcadeId: motorcade._id
					}, transaction)
				}
			}

			await transaction.commit()
			//todo发送通知
		} catch (e) {
			await transaction.rollback()
			console.error(e)
			throw e
		}
	}

	async startWork({
		motorcadeId
	}) {
		const transaction = await this.db.startTransaction()
		try {
			let motorcade = await dbHelper.getById("t3ds-subscribe-motorcade", motorcadeId, transaction)
			if (!motorcade) {
				throw new Error("车队不存在")
			}
			let storeRes = await dbHelper.getById("t3ds-store", motorcade.storeId, transaction)
			console.log("storeRes: ", storeRes);
			if (!(storeRes.cooperationMode === 'merchant' && storeRes.uid === this.ctx.auth.uid && this.ctx.auth
					.role.includes('boss'))) { // 不是合作门店老板
				if (motorcade.compereId != this.ctx.auth.uid) {
					throw new Error("无权限")
				}
			}

			if (motorcade.status != 3) {
				throw new Error("已开始或已结束")
			}
			await dbHelper.update("t3ds-subscribe-motorcade", {
				_id: motorcadeId,
				status: 4,
				startWorkTime: Date.now(),
				updateTime: Date.now(),
				updateBy: this.ctx.auth.userInfo.username
			}, transaction)
			await dbHelper.update("uni-id-users", {
				_id: this.ctx.auth.uid,
				compereStatus: {
					status: 1,
					storeName: motorcade.storeName,
					scriptName: motorcade.name,
				}
			}, transaction)
			await transaction.commit()
			//todo发送通知
		} catch (e) {
			await transaction.rollback()
			throw e
		}
	}

	async confirmOrder({
		motorcadeId
	}) {
		const transaction = await this.db.startTransaction()
		try {
			let motorcade = await dbHelper.getById("t3ds-subscribe-motorcade", motorcadeId, transaction)
			if (!motorcade) {
				throw new Error("车队不存在")
			}
			let record = await dbHelper.getOne("t3ds-motorcade-assign-record", {
				motorcadeId,
				compereId: this.ctx.auth.uid,
				status: 0
			})
			if (!record) {
				throw new Error("未查到订单信息")
			}
			await dbHelper.update("t3ds-motorcade-assign-record", {
				_id: record._id,
				status: 1,
				updateTime: Date.now(),
				updateBy: this.ctx.auth.userInfo.username
			}, transaction)
			await dbHelper.update("t3ds-subscribe-motorcade", {
				_id: motorcadeId,
				status: 3,
				updateTime: Date.now(),
				updateBy: this.ctx.auth.userInfo.username
			}, transaction)
			await transaction.commit()
			//todo发送通知
			try {
				const dbCmd = this.db.command
				let compere = await dbHelper.getById('uni-id-users', motorcade.compereId)
				let admins = []
				// 共享超管、共享区管
				admins = await dbHelper.getList("uni-id-users", dbCmd.or([{
					role: dbCmd.eq('admin')
				}, {
					role: dbCmd.eq('share_mgr'),
					city: compere.city
				}]))
				console.log("admins: ", admins);
				for (var i = 0; i < admins.length; i++) {
					let service = admins[i]
					if (service.merchant_info && service.merchant_info.wx_unionid) {
						let wxPubUser = await dbHelper.getOne("t3ds-wx-pub-user", {
							unionId: service.merchant_info.wx_unionid,
							city: compere.city
						})
						if (wxPubUser && wxPubUser.openId) {
							let temp = await dbHelper.getOne('t3ds-region', {
								'city.value': compere.city
							})
							let tempId = temp.templateMsgs.find(item => {
								return item.templateName === '新订单通知'
							}).templateID
							let msg = createNoticeMsg(wxPubUser.openId, tempId, motorcade, compere, '主持人接单通知');
							await wxPubApi.sendTemplateMsg(compere.city, msg)
						} else {
							console.warn('用户未关注公众号，无法发送通知，用户_id', service._id, wxPubUser)
						}
					} else {
						console.warn('用户未绑定微信，无法发送通知，用户_id', service._id, service)
					}
				}
			} catch (e) {
				console.error("发送主持人接单通知遇到错误", e);
			}
		} catch (e) {
			await transaction.rollback()
			throw e
		}
	}

	async refuseOrder({
		motorcadeId,
		reason
	}) {
		const transaction = await this.db.startTransaction()
		try {
			let motorcade = await dbHelper.getById("t3ds-subscribe-motorcade", motorcadeId, transaction)
			if (!motorcade) {
				throw new Error("车队不存在")
			}

			let isCooperationStoreBoss = await dbHelper.getOne('t3ds-store', {
				uid: this.ctx.auth.uid,
				cooperationMode: 'merchant'
			})
			if (!isCooperationStoreBoss) { // 不是合作门店的老板
				let record = await dbHelper.getOne("t3ds-motorcade-assign-record", {
					motorcadeId,
					compereId: this.ctx.auth.uid,
					status: 0
				})
				if (!record) {
					throw new Error("未查到订单信息")
				}
				await dbHelper.update("t3ds-motorcade-assign-record", {
					_id: record._id,
					refusedReason: reason,
					status: 2,
					updateTime: Date.now(),
					updateBy: this.ctx.auth.userInfo.username
				}, transaction)
			}

			await dbHelper.update("t3ds-subscribe-motorcade", {
				_id: motorcadeId,
				status: -2,
				refusedReason: reason,
				updateTime: Date.now(),
				updateBy: this.ctx.auth.userInfo.username
			}, transaction)
			await transaction.commit()
			//todo发送通知
			try {
				const dbCmd = this.db.command
				let compere = await dbHelper.getById('uni-id-users', motorcade.compereId)
				let admins = []
				// 共享超管、共享区管
				admins = await dbHelper.getList("uni-id-users", dbCmd.or([{
					role: dbCmd.eq('admin')
				}, {
					role: dbCmd.eq('share_mgr'),
					city: compere.city
				}]))
				console.log("admins: ", admins);
				for (var i = 0; i < admins.length; i++) {
					let service = admins[i]
					if (service.merchant_info && service.merchant_info.wx_unionid) {
						let wxPubUser = await dbHelper.getOne("t3ds-wx-pub-user", {
							unionId: service.merchant_info.wx_unionid,
							city: compere.city
						})
						if (wxPubUser && wxPubUser.openId) {
							let temp = await dbHelper.getOne('t3ds-region', {
								'city.value': compere.city
							})
							let tempId = temp.templateMsgs.find(item => {
								return item.templateName === '新订单通知'
							}).templateID
							let msg = createNoticeMsg(wxPubUser.openId, tempId, motorcade, compere,
							'主持人拒绝接单通知');
							await wxPubApi.sendTemplateMsg(compere.city, msg)
						} else {
							console.warn('用户未关注公众号，无法发送通知，用户_id', service._id, wxPubUser)
						}
					} else {
						console.warn('用户未绑定微信，无法发送通知，用户_id', service._id, service)
					}
				}
			} catch (e) {
				console.error("发送拒绝通知遇到错误", e);
			}
		} catch (e) {
			await transaction.rollback()
			throw e
		}
	}

	async cancelMotorcade({
		motorcadeId,
		reason
	}) {
		const transaction = await this.db.startTransaction()
		try {
			let motorcade = await dbHelper.getById("t3ds-subscribe-motorcade", motorcadeId, transaction);
			if (!motorcade) {
				throw new Error("车队不存在")
			}
			let user = await dbHelper.getById("uni-id-users", this.ctx.auth.uid)
			await orderHelper.cancelMotorcade({
				motorcade,
				serviceCharge: 0,
				handleMan: user.username,
				reason,
				transaction
			})
			//todo通知用户
			await transaction.commit()
		} catch (e) {
			await transaction.rollback()
			throw e
		}
	}

	async assignCompere({
		motorcadeId,
		compereId
	}) {
		const dbCmd = this.db.command
		const transaction = await this.db.startTransaction()
		try {
			let motorcade = await dbHelper.getById("t3ds-subscribe-motorcade", motorcadeId, transaction);
			if (!motorcade) {
				throw new Error("车队不存在")
			}
			if (motorcade.status > 2) {
				throw new Error("已确认不能再分配")
			}
			let compere = await dbHelper.getById("uni-id-users", compereId)
			if (!compere) {
				throw new Error("主持人不存在")
			}
			let count = await dbHelper.getCount("t3ds-motorcade-assign-record", {
				motorcadeId,
				compereId,
				status: 0
			})
			if (count) {
				throw new Error("已分配，无需再次分配")
			}
			//取消先前分配的
			let record = await dbHelper.getOne("t3ds-motorcade-assign-record", {
				motorcadeId,
				status: 0
			})
			if (record) {
				await dbHelper.update("t3ds-motorcade-assign-record", {
					_id: record._id,
					status: -1
				}, transaction)
			}
			let user = await dbHelper.getById("uni-id-users", this.ctx.auth.uid)
			let logs = motorcade.operationLogs || []
			logs.unshift({
				action: '分配主持人',
				time: Date.now(),
				createBy: user.username
			})
			await dbHelper.update("t3ds-subscribe-motorcade", {
				_id: motorcadeId,
				status: 2,
				compereId,
				operationLogs: logs,
				refusedReason: '',
				updateTime: Date.now(),
				updateBy: this.ctx.auth.userInfo.username
			}, transaction)
			await dbHelper.insert("t3ds-motorcade-assign-record", {
				compereId,
				compereName: `${compere.nickname || compere.username}(${compere.id})`,
				motorcadeId,
				motorcadeName: motorcade.name,
				createTime: Date.now(),
				createBy: user.nickname || user.username,
				status: 0
			}, transaction)
			//todo通知用户
			try {
				if (compere.merchant_info.wx_unionid) {
					let wxPubUser = await dbHelper.getOne("t3ds-wx-pub-user", {
						unionId: compere.merchant_info.wx_unionid,
						city: compere.city
					})
					if (wxPubUser.openId) {
						let temp = await dbHelper.getOne('t3ds-region', {
							'city.value': compere.city
						})
						let tempId = temp.templateMsgs.find(item => {
							return item.templateName === '新订单通知'
						}).templateID
						let user = await dbHelper.getOne('uni-id-users', {
							id: motorcade.initiator
						})
						let msg = createNoticeMsg(wxPubUser.openId, tempId, motorcade, user, '收到一条新的订单',
							'motorcade-list-dm');
						await wxPubApi.sendTemplateMsg(compere.city, msg)
					} else {
						console.log("用户没有关注公众号，无法发送通知")
					}
				} else {
					console.log("用户没有unionId，无法发送通知")
				}
			} catch (e) {
				console.error("发送通知遇到错误", e);
			}
			await transaction.commit()
		} catch (e) {
			await transaction.rollback()
			throw e
		}
	}

	// 合作门店老板接车队单
	async cooperativeStoreReceiveOrder({
		motorcadeId
	}) {
		const transaction = await this.db.startTransaction()
		const dbCmd = this.db.command
		const $ = dbCmd.aggregate

		try {
			let userRes = await dbHelper.getById("uni-id-users", this.ctx.auth.uid, transaction)
			if (!userRes.role.some(role => role === 'boss')) throw '无接单权限'

			let motorcadeRes = await dbHelper.getById("t3ds-subscribe-motorcade", motorcadeId, transaction)
			console.log("motorcadeRes: ", motorcadeRes);
			if (!motorcadeRes) throw "车队不存在"
			if (motorcadeRes.status > 2) throw "已确认接单不能再接单"

			let storeRes = await dbHelper.getById("t3ds-store", motorcadeRes.storeId, transaction)
			if (storeRes.cooperationMode !== 'merchant') throw "车队所在门店不是合作门店"

			let logs = motorcadeRes.operationLogs || []
			logs.unshift({
				action: '合作门店老板接单',
				time: Date.now(),
				createBy: userRes.username
			})
			await dbHelper.update("t3ds-subscribe-motorcade", {
				_id: motorcadeId,
				status: 3,
				operationLogs: logs,
				refusedReason: dbCmd.remove(),
				updateTime: Date.now(),
				updateBy: userRes.username
			}, transaction)

			await transaction.commit()
			return
		} catch (e) {
			await transaction.rollback()
			throw e
		}
	}

	// 合作门店老板结束车队单
	async endService({
		motorcadeId
	}) {
		const transaction = await this.db.startTransaction()

		const dbCmd = this.db.command
		const $ = dbCmd.aggregate

		try {
			let userRes = await dbHelper.getById("uni-id-users", this.ctx.auth.uid, transaction)
			if (!userRes.role.some(role => role === 'boss')) throw '无结束服务权限'

			let motorcadeRes = await dbHelper.getById("t3ds-subscribe-motorcade", motorcadeId, transaction)
			if (!motorcadeRes) throw "车队不存在"
			// if (motorcadeRes.endTime > Date.now()) throw "车队尚未到结束时间"
			if (motorcadeRes.status !== 4) throw "已结束或未确认"

			// 更新车队记录
			let logs = motorcadeRes.operationLogs || []
			logs.unshift({
				action: '合作门店车队结算',
				time: Date.now(),
				createBy: this.ctx.auth.userInfo.username
			})
			await dbHelper.update("t3ds-subscribe-motorcade", {
				_id: motorcadeId,
				status: 5,
				finishWorkTime: Date.now(),
				updateTime: Date.now(),
				updateBy: this.ctx.auth.userInfo.username,
				operationLogs: logs
			}, transaction)

			// 更新车队关联订单
			let relevanceOrderRes = await dbHelper.getList('t3ds-order', {
				motorcadeId
			}, transaction)
			// console.log("relevanceOrderRes: ",relevanceOrderRes);
			for (let i = 0; i < relevanceOrderRes.length; i++) {
				await dbHelper.update('t3ds-order', {
					_id: relevanceOrderRes[i]._id,
					status: 4,
					updateBy: userRes.username,
					update_time: Date.now()
				}, transaction)
			}
			// 结算门店佣金
			let ordersIdRes = []
			if (motorcadeRes.renewalOrders && motorcadeRes.renewalOrders.length) {
				let foo = motorcadeRes.renewalOrders.map(item => {
					let bar = item.renewalOrdersId.map(item2 => item2.renewalOrdersId)
					ordersIdRes.concat(bar)
					return bar
				})
			}
			ordersIdRes = [...new Set(ordersIdRes.concat(motorcadeRes.orderIds))]
			console.log("ordersIdRes: ", ordersIdRes);
			let storeRes = await dbHelper.getById("t3ds-store", motorcadeRes.storeId, transaction)
			if (storeRes.cooperationMode === 'merchant') { // 合作门店
				let totalFeeRes = await transaction.collection("t3ds-order")
					.aggregate()
					.match({
						_id: dbCmd.in(ordersIdRes)
					})
					.group({
						_id: null,
						totalFee: $.sum("$total_fee")
					})
					.end()
				let totalFee = totalFeeRes.data[0].totalFee
				if (totalFee) {
          let serviceChargeConfig = null
          if (!storeRes.commissionRatio) {
            serviceChargeConfig = await dbHelper.getOne("t3ds-system-config", {
            	key: "serviceCharge"
            })
            if (!serviceChargeConfig) { throw new Error("平台抽成比例未配置，请联系管理员") }
          }
          let serviceCharge = Math.round(parseInt(storeRes.commissionRatio || serviceChargeConfig.value) / 100 * totalFee)
					let income = totalFee - serviceCharge
					console.log(`合作门店收入: ${income / 100}元，平台抽成：${serviceCharge / 100}元`)

					let account = await dbHelper.getOne("t3ds-account", {
						userId: storeRes.uid
					}, transaction)
					console.log("account: ", account);
					if (!account) {
						account = {
							userId: storeRes.uid,
							balance: 0,
							frozen: 0,
							settle: 0,
							total: 0
						}
						await dbHelper.insert("t3ds-account", account, transaction)
					}
					account = await dbHelper.getById("t3ds-account", account._id, transaction)
					await dbHelper.update("t3ds-account", {
						_id: account._id,
						balance: dbCmd.inc(income),
						total: dbCmd.inc(income),
						updateBy: '系统',
						updateTime: Date.now()
					}, transaction)
					console.log("account._id: ", account._id);
					await dbHelper.insert("t3ds-account-log", {
						accountId: account._id,
						userId: storeRes.uid,
						income: income,
						settled: true,
						tradeType: 12,
						settleTime: Date.now(),
						total: account.total + income,
						createTime: Date.now(),
						createBy: '系统',
						motorcadeId
					}, transaction)
				}
			}

			await transaction.commit()
			return {
				code: 200
			}
		} catch (e) {
			await transaction.rollback()
			console.error(e)
			throw e
		}
	}

	// 共享超管修改订单
	async modifyOrder({
		motorcadeId,
		storeId,
		roomId
	}) {
		const transaction = await this.db.startTransaction()
		const dbCmd = this.db.command
		const $ = dbCmd.aggregate

		try {
			let userRes = await dbHelper.getById("uni-id-users", this.ctx.auth.uid, transaction)
			if (!userRes.role.some(role => role === 'share_mgr')) throw '无修改订单权限'

			let motorcadeRes = await dbHelper.getById("t3ds-subscribe-motorcade", motorcadeId, transaction)
			if (!motorcadeRes) throw "车队不存在"

			let storeRes = await dbHelper.getById("t3ds-store", storeId, transaction)
			if (!storeRes) throw "门店不存在"

			let roomRes = null
			if (roomId) {
				roomRes = await dbHelper.getById("t3ds-store-room", roomId, transaction)
				if (!roomRes) throw "包间不存在"
				if (motorcadeRes.storeId !== storeId || motorcadeRes.roomId !== roomId) { // 门店或包间没改变则不判断
					// 判断是否锁房间
					let roomLocked = await this.service.order.checkRoomLocked(roomId, motorcadeRes.startTime,
						motorcadeRes.endTime)
					if (roomLocked) throw "该时间段的包间已被预定，请重新选择门店和包间"
				}
			}
			console.log("roomRes: ", roomRes);

			// 更新车队记录
			let newMotorcade = JSON.parse(JSON.stringify(motorcadeRes))
			let logs = newMotorcade.operationLogs || []
			logs.unshift({
				action: `共享超管修改车队及订单`,
				time: Date.now(),
				createBy: userRes.username
			})
			newMotorcade.storeId = storeRes._id
			newMotorcade.storeName = storeRes.name
			newMotorcade.address = storeRes.address
			newMotorcade.location = storeRes.location
			newMotorcade.roomId = roomRes ? roomRes._id : dbCmd.remove()
			newMotorcade.roomName = roomRes ? roomRes.name : dbCmd.remove()
			newMotorcade.status = storeRes.cooperationMode === 'merchant' ? 2 : 1
			newMotorcade.operationLogs = logs
			newMotorcade.updateTime = Date.now()
			newMotorcade.updateBy = userRes.username
			newMotorcade.refusedReason = dbCmd.remove()
			newMotorcade.compereId = dbCmd.remove()
			console.log("newMotorcade: ", newMotorcade);
			await dbHelper.update("t3ds-subscribe-motorcade", newMotorcade, transaction)

			// 更新车队关联订单
			let relevanceOrderRes = await dbHelper.getList('t3ds-order', {
				motorcadeId
			}, transaction)
			// console.log("relevanceOrderRes: ",relevanceOrderRes);
			for (let i = 0; i < relevanceOrderRes.length; i++) {
				relevanceOrderRes[i].updateBy = userRes.username
				relevanceOrderRes[i].update_time = Date.now()

				let newItem = JSON.parse(JSON.stringify(relevanceOrderRes[i].items[0]))
				if (newItem.room_id) {
					delete newItem.room_capacity
					delete newItem.room_id
					delete newItem.room_name
					delete newItem.room_price
				}
				if (roomRes) {
					newItem.room_capacity = roomRes.capacity
					newItem.room_id = roomRes._id
					newItem.room_name = roomRes.name
					newItem.room_price = roomRes.price
				} else {
					newItem.store_id = storeRes._id
					newItem.store_name = storeRes.name
					newItem.unifyPrice = storeRes.unifyPrice
				}
				relevanceOrderRes[i].items[0] = newItem
				await dbHelper.update('t3ds-order', relevanceOrderRes[i], transaction)
			}

			await transaction.commit()
			return {
				code: 200
			}
		} catch (e) {
			await transaction.rollback()
			return {
				code: 500,
				msg: e
			}
		}
	}
	
	// 确认接单（商品车队）
	async confirmGoodsOrder({
		motorcadeId
	}) {
		const transaction = await this.db.startTransaction()
		try {
			let motorcade = await dbHelper.getById("t3ds-motorcade", motorcadeId, transaction)
			if (!motorcade) {
				throw new Error("车队不存在")
			}
			// let record = await dbHelper.getOne("t3ds-motorcade-assign-record", {
			// 	motorcadeId,
			// 	compereId: this.ctx.auth.uid,
			// 	status: 0
			// })
			// if (!record) {
			// 	throw new Error("未查到订单信息")
			// }
			// await dbHelper.update("t3ds-motorcade-assign-record", {
			// 	_id: record._id,
			// 	status: 1,
			// 	updateTime: Date.now(),
			// 	updateBy: this.ctx.auth.userInfo.username
			// }, transaction)
			await dbHelper.update("t3ds-motorcade", {
				_id: motorcadeId,
				status: 2,
				updateTime: Date.now(),
				updateBy: this.ctx.auth.userInfo.username
			}, transaction)
			await transaction.commit()
			//给用户发拼车成功的通知
			//todo发送通知
			// try {
			// 	const dbCmd = this.db.command
			// 	let compere = await dbHelper.getById('uni-id-users', motorcade.compereId)
			// 	let admins = []
			// 	// 共享超管、共享区管
			// 	admins = await dbHelper.getList("uni-id-users", dbCmd.or([{
			// 		role: dbCmd.eq('admin')
			// 	}, {
			// 		role: dbCmd.eq('share_mgr'),
			// 		city: compere.city
			// 	}]))
			// 	console.log("admins: ", admins);
			// 	for (var i = 0; i < admins.length; i++) {
			// 		let service = admins[i]
			// 		if (service.merchant_info && service.merchant_info.wx_unionid) {
			// 			let wxPubUser = await dbHelper.getOne("t3ds-wx-pub-user", {
			// 				unionId: service.merchant_info.wx_unionid,
			// 				city: compere.city
			// 			})
			// 			if (wxPubUser && wxPubUser.openId) {
			// 				let temp = await dbHelper.getOne('t3ds-region', {
			// 					'city.value': compere.city
			// 				})
			// 				let tempId = temp.templateMsgs.find(item => {
			// 					return item.templateName === '新订单通知'
			// 				}).templateID
			// 				let msg = createNoticeMsg(wxPubUser.openId, tempId, motorcade, compere, '主持人接单通知');
			// 				await wxPubApi.sendTemplateMsg(compere.city, msg)
			// 			} else {
			// 				console.warn('用户未关注公众号，无法发送通知，用户_id', service._id, wxPubUser)
			// 			}
			// 		} else {
			// 			console.warn('用户未绑定微信，无法发送通知，用户_id', service._id, service)
			// 		}
			// 	}
			// } catch (e) {
			// 	console.error("发送主持人接单通知遇到错误", e);
			// }
		} catch (e) {
			await transaction.rollback()
			throw e
		}
	}
	
	//拒绝接单
	async refuseGoodsOrder({
		motorcadeId,
		reason
	}) {
		const transaction = await this.db.startTransaction()
		try {
			let motorcade = await dbHelper.getById("t3ds-motorcade", motorcadeId, transaction)
			if (!motorcade) {
				throw new Error("车队不存在")
			}
			// let isCooperationStoreBoss = await dbHelper.getOne('t3ds-store', {
			// 	uid: this.ctx.auth.uid,
			// 	cooperationMode: 'merchant'
			// })
			// if (!isCooperationStoreBoss) { // 不是合作门店的老板
			// 	let record = await dbHelper.getOne("t3ds-motorcade-assign-record", {
			// 		motorcadeId,
			// 		compereId: this.ctx.auth.uid,
			// 		status: 0
			// 	})
			// 	if (!record) {
			// 		throw new Error("未查到订单信息")
			// 	}
			// 	await dbHelper.update("t3ds-motorcade-assign-record", {
			// 		_id: record._id,
			// 		refusedReason: reason,
			// 		status: 2,
			// 		updateTime: Date.now(),
			// 		updateBy: this.ctx.auth.userInfo.username
			// 	}, transaction)
			// }
	
			await dbHelper.update("t3ds-motorcade", {
				_id: motorcadeId,
				status: -2,
				refusedReason: reason,
				refuseTime: Date.now(),
				updateTime: Date.now(),
				updateBy: this.ctx.auth.userInfo.username
			}, transaction)
			await transaction.commit()
			//给用户发拼车失败的通知
			//todo发送通知
			// try {
			// 	const dbCmd = this.db.command
			// 	let compere = await dbHelper.getById('uni-id-users', motorcade.compereId)
			// 	let admins = []
			// 	// 共享超管、共享区管
			// 	admins = await dbHelper.getList("uni-id-users", dbCmd.or([{
			// 		role: dbCmd.eq('admin')
			// 	}, {
			// 		role: dbCmd.eq('share_mgr'),
			// 		city: compere.city
			// 	}]))
			// 	console.log("admins: ", admins);
			// 	for (var i = 0; i < admins.length; i++) {
			// 		let service = admins[i]
			// 		if (service.merchant_info && service.merchant_info.wx_unionid) {
			// 			let wxPubUser = await dbHelper.getOne("t3ds-wx-pub-user", {
			// 				unionId: service.merchant_info.wx_unionid,
			// 				city: compere.city
			// 			})
			// 			if (wxPubUser && wxPubUser.openId) {
			// 				let temp = await dbHelper.getOne('t3ds-region', {
			// 					'city.value': compere.city
			// 				})
			// 				let tempId = temp.templateMsgs.find(item => {
			// 					return item.templateName === '新订单通知'
			// 				}).templateID
			// 				let msg = createNoticeMsg(wxPubUser.openId, tempId, motorcade, compere,
			// 				'主持人拒绝接单通知');
			// 				await wxPubApi.sendTemplateMsg(compere.city, msg)
			// 			} else {
			// 				console.warn('用户未关注公众号，无法发送通知，用户_id', service._id, wxPubUser)
			// 			}
			// 		} else {
			// 			console.warn('用户未绑定微信，无法发送通知，用户_id', service._id, service)
			// 		}
			// 	}
			// } catch (e) {
			// 	console.error("发送拒绝通知遇到错误", e);
			// }
		} catch (e) {
			await transaction.rollback()
			throw e
		}
	}
	
	//获取剧本车队列表
	async getSubscribeList({
		city,
		userLocation
	}) {
		const db = uniCloud.database()
		const dbCmd = this.db.command
		const $ = dbCmd.aggregate
		try {
			let res = await db.collection("t3ds-subscribe-motorcade").aggregate().geoNear({
			      near: new db.Geo.Point(userLocation.longitude,userLocation.latitude),
			      query: {
			       city: city,
			       status: 0,
			       startTime: dbCmd.gt(Date.now())
			      },
			      spherical: true,
			      distanceField: 'distance'
			     })
			     .addFields({
			      playersCount: $.sum(['$currentFemaleCount', '$currentMaleCount']),
			     })
			     .project({
			      startTime: 1,
			      endTime: 1,
			      costPerPerson: 1,
			      thumbnail: 1,
			      name: 1,
			      needCount: $.cond({
			       if: '$allowGetOn',
			       then: $.subtract(["$maxPlayers", "$playersCount"]),
			       else: $.subtract(["$minPlayers", "$playersCount"])
			      }),
			      deadline: $.subtract(["$startTime", Date.now()]),
			      storeName: 1,
			      roomName: 1,
			      roomId: 1,
			      storeId: 1,
			      allowGetOn: 1,
			      scriptId: 1
			     })
			     .sort({
			      distance: 1,
			      needCount: 1,
			      deadline: 1
			     })
			     .limit(2)
			     .end()
			return res.data
		} catch (e) {
			throw e
		}
	}
	
	//获取门店列表
	async getStoreList({
		city,
		userLocation
	}) {
		const db = uniCloud.database()
		const dbCmd = this.db.command
		const $ = dbCmd.aggregate
		try {
			let res = await db.collection("t3ds-store").aggregate().geoNear({
			      near: new db.Geo.Point(userLocation.longitude, userLocation.latitude),
			      query: {
			       'region.city.value': city,
			       enabled: true,
			       joinSharePlan: true
			      },
			      spherical: true,
			      // maxDistance: 20000000,
			      distanceField: 'distance'
			     })
			     .project({
			      thumbnail: $.arrayElemAt(['$photos', 0]),
			      name: 1,
			      address: 1,
			      distance: 1
			     })
			     .sort({
			      distance: 1
			     })
			     .limit(2)
			     .end()
			return res.data
		} catch (e) {
			throw e
		}
	}
}
